package com.adcc.automation.gui.Controller;

import com.adcc.automation.communication.CommunicationHandler;
import com.adcc.automation.config.YmlConfig;
import com.adcc.automation.gui.event.ConnectStatusEvent;
import com.adcc.automation.service.configuration.ConnectionStatus;
import com.adcc.automation.service.util.TimeUtil;
import com.adcc.automation.service.util.XmlConverter;
import com.jfoenix.controls.JFXButton;
import io.datafx.controller.ViewController;
import io.datafx.controller.flow.context.FXMLViewFlowContext;
import io.datafx.controller.flow.context.ViewFlowContext;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@ViewController(value = "/fxml/main.fxml", title = "automation verification app")
public class MainController {
    private final int maxNum = 20;
    private static final Logger logger = LoggerFactory.getLogger(MainController.class);
    ScheduledExecutorService topic1Ses;
    ScheduledExecutorService topic2Ses;
    @FXMLViewFlowContext
    private ViewFlowContext context;
    @FXML
    private TextField url;
    @FXML
    private TextField user;
    @FXML
    private TextField password;
    @FXML
    private TextField recvTopic1;
    @FXML
    private TextField sendTopic1;
    @FXML
    private TextField fplQueue1;
    @FXML
    private TextField recvCommandQueue1;
    @FXML
    private TextField sendCommandQueue1;
    @FXML
    private TextField recvTopic2;
    @FXML
    private TextField sendTopic2;
    @FXML
    private TextField fplQueue2;
    @FXML
    private TextField recvCommandQueue2;
    @FXML
    private TextField sendCommandQueue2;
    @FXML
    private TextField hbSendInterval;
    @FXML
    private Label topic1_num;
    @FXML
    private Label send_command1_num;
    @FXML
    private Label topic2_num;
    @FXML
    private Label send_command2_num;
    @FXML
    private Label recv_topic1_num;
    @FXML
    private Label recv_command1_num;
    @FXML
    private Label recv_topic2_num;
    @FXML
    private Label recv_command2_num;
    @FXML
    private Label fpl1_num;
    @FXML
    private Label fpl2_num;
    @FXML
    private TextArea topic1_area;
    @FXML
    private TextArea command1_area;
    @FXML
    private TextArea topic2_area;
    @FXML
    private TextArea command2_area;
    @FXML
    private TextArea recv_topic1_area;
    @FXML
    private TextArea recv_command1_area;
    @FXML
    private TextArea recv_topic2_area;
    @FXML
    private TextArea recv_command2_area;
    @FXML
    private TextArea fpl1_area;
    @FXML
    private TextArea fpl2_area;
    @FXML
    private JFXButton connectButton;
    @FXML
    private JFXButton clearButton;
    @FXML
    private JFXButton topic1_continuous_send_button;
    @FXML
    private JFXButton topic1_send_button;
    @FXML
    private JFXButton send_command_button1;
    @FXML
    private JFXButton topic2_continuous_send_button;
    @FXML
    private JFXButton topic2_send_button;
    @FXML
    private JFXButton send_command_button2;
    @FXML
    private JFXButton fpl1_send_button;
    @FXML
    private JFXButton fpl2_send_button;
    private ConnectionStatus status;
    
    @PostConstruct
    public void initUI() {
        context.register("main", this);
        //加载代理类
        CommunicationHandler.getInstance().setContext(context);
        //初始化UI
        //绑定默认值
        url.setText("tcp://127.0.0.1:61616");
        user.setText("admin");
        password.setText("admin");
        recvTopic1.setText("T.HB.DCL");
        sendTopic1.setText("T.HB.EFS");
        fplQueue1.setText("Q.FPL1");
        recvCommandQueue1.setText("Q.DCL.TO.EFS1");
        sendCommandQueue1.setText("Q.EFS.TO.DCL1");
        recvTopic2.setText("T.HB.DCL");
        sendTopic2.setText("T.HB.EFS");
        fplQueue2.setText("Q.FPL2");
        recvCommandQueue2.setText("Q.DCL.TO.EFS2");
        sendCommandQueue2.setText("Q.EFS.TO.DCL2");
        hbSendInterval.setText("5");
        status = ConnectionStatus.DISCONNECTED;
    }
    
    /**
     * 连接断开mq
     */
    @FXML
    private void connAction(ActionEvent event) {
        if (status == ConnectionStatus.DISCONNECTED) {
            try {
                //准备参数
                Map<String, Object> map1 = new HashMap<>();
                Map<String, Object> map2 = new HashMap<>();
                map1.put("url", url.getText());
                map1.put("user", user.getText());
                map1.put("password", password.getText());
                map1.put("recvTopic", recvTopic1.getText());
                map1.put("sendTopic", sendTopic1.getText());
                map1.put("fplQueue", fplQueue1.getText());
                map1.put("recvCommandQueue", recvCommandQueue1.getText());
                map1.put("sendCommandQueue", sendCommandQueue1.getText());
                map1.put("hbSendInterval", Integer.parseInt(hbSendInterval.getText()));
                
                map2.put("url", url.getText());
                map2.put("user", user.getText());
                map2.put("password", password.getText());
                map2.put("recvTopic", recvTopic2.getText());
                map2.put("sendTopic", sendTopic2.getText());
                map2.put("fplQueue", fplQueue2.getText());
                map2.put("recvCommandQueue", recvCommandQueue2.getText());
                map2.put("sendCommandQueue", sendCommandQueue2.getText());
                map2.put("hbSendInterval", Integer.parseInt(hbSendInterval.getText()));
                CommunicationHandler.getInstance().init(map1,map2).connect();
            } catch (Exception e) {
                logger.error("断开连接失败", e);
            }
        } else if (status == ConnectionStatus.CONNECTED) {
            try {
                CommunicationHandler.getInstance().disconnect();
            } catch (Exception e) {
                logger.error("连接失败", e);
            }
        }
    }
    
    //状态反馈
    public void connectHandler(ConnectStatusEvent event) {
        Platform.runLater(() -> {
            switch (event.getStatus()) {
                case "connected":
                    changeToConnected();
                    break;
                case "disconnected":
                    changeToDisconnected();
                    break;
                case "connecting":
                    changeToConnecting();
                    break;
            }
        });
    }
    
    private void changeToConnecting() {
        status = ConnectionStatus.CONNECTING;
        url.setDisable(true);
        user.setDisable(true);
        password.setDisable(true);
        recvTopic1.setDisable(true);
        sendTopic1.setDisable(true);
        fplQueue1.setDisable(true);
        recvCommandQueue1.setDisable(true);
        sendCommandQueue1.setDisable(true);
        recvTopic2.setDisable(true);
        sendTopic2.setDisable(true);
        fplQueue2.setDisable(true);
        recvCommandQueue2.setDisable(true);
        sendCommandQueue2.setDisable(true);
        hbSendInterval.setDisable(true);
        connectButton.setText("连接中...");
        topic1_continuous_send_button.setDisable(true);
        topic1_send_button.setDisable(true);
        send_command_button1.setDisable(true);
        topic2_continuous_send_button.setDisable(true);
        topic2_send_button.setDisable(true);
        send_command_button2.setDisable(true);
        fpl1_send_button.setDisable(true);
        fpl2_send_button.setDisable(true);
    }
    
    //连接成功更改ui
    public void changeToConnected() {
        status = ConnectionStatus.CONNECTED;
        url.setDisable(true);
        user.setDisable(true);
        password.setDisable(true);
        recvTopic1.setDisable(true);
        sendTopic1.setDisable(true);
        fplQueue1.setDisable(true);
        recvCommandQueue1.setDisable(true);
        sendCommandQueue1.setDisable(true);
        recvTopic2.setDisable(true);
        sendTopic2.setDisable(true);
        fplQueue2.setDisable(true);
        recvCommandQueue2.setDisable(true);
        sendCommandQueue2.setDisable(true);
        hbSendInterval.setDisable(true);
        connectButton.setText("断开");
        topic1_continuous_send_button.setDisable(false);
        topic1_send_button.setDisable(false);
        send_command_button1.setDisable(false);
        topic2_continuous_send_button.setDisable(false);
        topic2_send_button.setDisable(false);
        send_command_button2.setDisable(false);
        fpl1_send_button.setDisable(false);
        fpl2_send_button.setDisable(false);
    }
    
    //连接断开更改ui
    public void changeToDisconnected() {
        status = ConnectionStatus.DISCONNECTED;
        url.setDisable(false);
        user.setDisable(false);
        password.setDisable(false);
        recvTopic1.setDisable(false);
        sendTopic1.setDisable(false);
        fplQueue1.setDisable(false);
        recvCommandQueue1.setDisable(false);
        sendCommandQueue1.setDisable(false);
        recvTopic2.setDisable(false);
        sendTopic2.setDisable(false);
        fplQueue2.setDisable(false);
        recvCommandQueue2.setDisable(false);
        sendCommandQueue2.setDisable(false);
        hbSendInterval.setDisable(false);
        connectButton.setText("连接");
        topic1_continuous_send_button.setDisable(true);
        topic1_send_button.setDisable(true);
        send_command_button1.setDisable(true);
        topic2_continuous_send_button.setDisable(true);
        topic2_send_button.setDisable(true);
        send_command_button2.setDisable(true);
        fpl1_send_button.setDisable(true);
        fpl2_send_button.setDisable(true);
    }
    
    //清空
    @FXML
    public void clearAction(ActionEvent event) {
        topic1_area.clear();
        command1_area.clear();
        topic2_area.clear();
        command2_area.clear();
        recv_topic1_area.clear();
        recv_command1_area.clear();
        recv_topic2_area.clear();
        recv_command2_area.clear();
        fpl1_area.clear();
        fpl2_area.clear();
        topic1_num.setText("0");
        send_command1_num.setText("0");
        topic2_num.setText("0");
        send_command2_num.setText("0");
        recv_topic1_num.setText("0");
        recv_command1_num.setText("0");
        recv_topic2_num.setText("0");
        recv_command2_num.setText("0");
        fpl1_num.setText("0");
        fpl2_num.setText("0");
    }
    
    @FXML
    public void sendTopic1() {
        String text = topic1_area.getText();
        String queue = sendTopic1.getText();
        if (text.isEmpty() || queue.isEmpty()) {
            return;
        }
        CommunicationHandler.getInstance().sendMsg(1,queue, text);
    }
    
    @FXML
    public void continuousSendTopic1() {
        if (topic1Ses != null) {
            topic1Ses.shutdown();
            topic1Ses = null;
            topic1_continuous_send_button.setText("连续发送");
            return;
        }
        
        String text = topic1_area.getText();
        String queue = sendTopic1.getText();
        if (text.isEmpty() || queue.isEmpty()) {
            return;
        }
        if (topic1Ses == null || topic1Ses.isShutdown()) {
            topic1Ses = Executors.newSingleThreadScheduledExecutor();
        }
        String hbSendInterval = this.hbSendInterval.getText();
        if (hbSendInterval.isEmpty()) {
            return;
        }
        topic1Ses.scheduleAtFixedRate(() -> CommunicationHandler.getInstance().sendMsg(1,queue, text), 0, Long.parseLong(hbSendInterval), TimeUnit.SECONDS);
        
        topic1_continuous_send_button.setText("停止");
    }
    
    @FXML
    public void sendTopic2() {
        String text = topic2_area.getText();
        String queue = sendTopic2.getText();
        if (text.isEmpty() || queue.isEmpty()) {
            return;
        }
        CommunicationHandler.getInstance().sendMsg(2,queue, text);
    }
    
    @FXML
    public void continuousSendTopic2() {
        if (topic2Ses != null) {
            topic2Ses.shutdown();
            topic2Ses = null;
            topic2_continuous_send_button.setText("连续发送");
            return;
        }
        String text = topic2_area.getText();
        String queue = sendTopic2.getText();
        if (text.isEmpty() || queue.isEmpty()) {
            return;
        }
        if (topic2Ses == null || topic2Ses.isShutdown()) {
            topic2Ses = Executors.newSingleThreadScheduledExecutor();
        }
        String hbSendInterval = this.hbSendInterval.getText();
        if (hbSendInterval.isEmpty()) {
            return;
        }
        topic2Ses.scheduleAtFixedRate(() -> CommunicationHandler.getInstance().sendMsg(2,queue, text), 0, Long.parseLong(hbSendInterval), TimeUnit.SECONDS);
        
        topic2_continuous_send_button.setText("停止");
    }
    @FXML
    public void sendCommandQueue1() {
        String text = command1_area.getText();
        String queue = sendCommandQueue1.getText();
        if (text.isEmpty() || queue.isEmpty()) {
            return;
        }
        CommunicationHandler.getInstance().sendMsg(1,queue, text);
    }
    @FXML
    public void sendCommandQueue2() {
        String text = command2_area.getText();
        String queue = sendCommandQueue2.getText();
        if (text.isEmpty() || queue.isEmpty()) {
            return;
        }
        CommunicationHandler.getInstance().sendMsg(2,queue, text);
    }
    @FXML
    public void sendFpl1(){
        String text = fpl1_area.getText();
        String queue = fplQueue1.getText();
        if (text.isEmpty() || queue.isEmpty()) {
            return;
        }
        CommunicationHandler.getInstance().sendMsg(1,queue, text);
    }
    @FXML
    public void sendFpl2(){
        String text = fpl2_area.getText();
        String queue = fplQueue2.getText();
        if (text.isEmpty() || queue.isEmpty()) {
            return;
        }
        CommunicationHandler.getInstance().sendMsg(2,queue, text);
    }
    public void updateSendTopic1Num() {
        Platform.runLater(() -> topic1_num.setText(String.valueOf(Integer.parseInt(topic1_num.getText()) + 1)));
    }
    
    public void updateSendTopic2Num() {
        Platform.runLater(() -> topic2_num.setText(String.valueOf(Integer.parseInt(topic2_num.getText()) + 1)));
    }
    
    public void updateSendCommandQueue1Num() {
        Platform.runLater(() -> send_command1_num.setText(String.valueOf(Integer.parseInt(send_command1_num.getText()) + 1)));
    }
    
    public void updateSendCommandQueue2Num() {
        Platform.runLater(() -> send_command2_num.setText(String.valueOf(Integer.parseInt(send_command2_num.getText()) + 1)));
    }
    public void updateSendFplQueue1Num() {
        Platform.runLater(() -> fpl1_num.setText(String.valueOf(Integer.parseInt(fpl1_num.getText()) + 1)));
    }
    public void updateSendFplQueue2Num() {
        Platform.runLater(() -> fpl2_num.setText(String.valueOf(Integer.parseInt(fpl2_num.getText()) + 1)));
    }
    
    public void updateTopic1(String text) {
        toView(text, recv_topic1_area, recv_topic1_num);
    }
    
    public void updateTopic2(String text) {
        toView(text, recv_topic2_area, recv_topic2_num);
    }
    
    public void updateFplQueue1(String text) {
        toView(text, fpl1_area, fpl1_num);
    }
    
    public void updateFplQueue2(String text) {
        toView(text, fpl2_area, fpl2_num);
    }
    
    public void updateCommandQueue1(String text) {
        toView(text, recv_command1_area, recv_command1_num);
        //判断开关启用
        YmlConfig config = YmlConfig.getInstance();
        if(config.getReply_switch() == 1){
            String ack = XmlConverter.convertAcarsToAck(text);
            if(ack != null){
                String queue = sendCommandQueue1.getText();
                CommunicationHandler.getInstance().sendMsg(1,queue, ack);
            }
        }
    }
    
    public void updateCommandQueue2(String text) {
        toView(text, recv_command2_area, recv_command2_num);
        //判断开关启用
        YmlConfig config = YmlConfig.getInstance();
        if(config.getReply_switch() == 1){
            String ack = XmlConverter.convertAcarsToAck(text);
            if(ack != null){
                String queue = sendCommandQueue2.getText();
                CommunicationHandler.getInstance().sendMsg(2,queue, ack);
            }
        }
    }
    
    private void toView(String text, TextArea recvCommand2Area, Label recvCommand2Num) {
        Platform.runLater(() -> {
            if (!recvCommand2Area.getText().isEmpty()) {
                recvCommand2Area.appendText("\r\n \r\n");
            }
            if (Integer.parseInt(recvCommand2Num.getText()) >= maxNum) {
                String currentText = recvCommand2Area.getText();
                int endIndex = currentText.indexOf("\n \n");
                if (endIndex != -1) { // 确保找到了 "\r\n"
                    StringBuilder sb = new StringBuilder(currentText);
                    sb.replace(0, endIndex + 2, ""); // "+ 2" 是为了包含 "\r\n" 这两个字符
                    recvCommand2Area.setText(sb.toString());
                }
            }
            recvCommand2Area.appendText(TimeUtil.createTime() + "\r\n");
            recvCommand2Area.appendText(text);
            recvCommand2Num.setText(String.valueOf(Integer.parseInt(recvCommand2Num.getText()) + 1));
            recvCommand2Area.setScrollTop(Double.MAX_VALUE);
        });
    }
}
